unit uPlanet;

interface

uses uBaseObject, uDefs;

type
  TPlanet = class( TBaseObject )
  public
    planetPopulation : integer;
    planetGrowth        : integer;
    planetMaxPopulation : integer;

    planetClimate         : enumClimate;   // Climate effects the growth rate of the population.
    planetMineral         : enumMineral;   // Higher means more minerals.
    planetGravity         : enumGravity;   // Gravity effects production rates, high gravity slows production and low gravity speeds it up.

    planetRotation        : real;       // How Fast it travels around the central object, 0=no orbit
    planetInitialRotation : real;       // Where its start from the central line
    planetOrbitDistance   : integer;    // Distance from central object.

    constructor Create();
    destructor Destroy(); override;
    procedure Reset();

    procedure OrbitRotation2D(CurrentAge:integer); //used for solarsystem view
    procedure OrbitRotation2DFromZero(CurrentAge:integer); //used for solarsystem view

    procedure tickerPopulation();
    procedure setPopulation(Value:integer);
  end;

  TPlanetList = class( TObject )
  public
    Count : integer;
    Items : array of TPlanet;
    constructor Create();
    destructor Destroy(); override;
    procedure reset();
    procedure addPlanet(theIndex,theOrbitPath:integer;theSystemName:string;theStarType:enumClimate;theStarSize:integer);
  end;

implementation

uses  cuDebug, cuFuncs, cuSimpleArrays, uSettings,
      SysUtils;

//============= Planet
constructor TPlanet.Create();
begin
  inherited;
end;
destructor TPlanet.Destroy();
begin
  inherited;
end;
procedure TPlanet.Reset();
begin
  inherited;

  planetPopulation      := 0;
  planetGrowth          := 0;
  planetMaxPopulation   := 0;

  planetClimate         := climateNONE;   // Climate effects the growth rate of the population.
  planetMineral         := mineralNONE;   // Higher means more minerals.
  planetGravity         := gravityNONE;   // Gravity effects production rates, high gravity slows production and low gravity speeds it up.

  planetRotation        := 0;       // How Fast it travels around the central object, 0=no orbit
  planetInitialRotation := 0;       // Where its start from the central line
  planetOrbitDistance   := 0;       // Distance from central object.
end;

procedure TPlanet.OrbitRotation2D(CurrentAge:integer);
var RotateAngle : real;
begin
  if (planetRotation = 0) then Exit;

  //NewOrbit
  RotateAngle := planetRotation*0.01;

  Vector2D.RotateMatrix(RotateAngle);

  DevConsole.Print(LOG_DEBUG3, 'TMyApp.OrbitRotation2D: Age #'+IntToStr(CurrentAge)+', Vector #'+Vector2D.ToXY );
end;
procedure TPlanet.OrbitRotation2DFromZero(CurrentAge:integer);
begin
  if (planetRotation <= 0) then Exit;

  Vector2D.setVector2D( 0, planetOrbitDistance ); //This resets the astros location to [0,orbitDistance]

  Vector2D.RotateMatrixUsingTime( planetRotation, planetInitialRotation, CurrentAge );

  DevConsole.Print(LOG_DEBUG3, 'TMyApp.OrbitRotation2DFromZero: Age #'+IntToStr(CurrentAge)+', Vector #'+Vector2D.ToXY );
end;

procedure TPlanet.tickerPopulation();
begin
  if (planetPopulation < planetMaxPopulation) then
    Inc( planetPopulation, planetGrowth );

  if (planetPopulation > planetMaxPopulation) then
    planetPopulation := planetMaxPopulation;
end;
procedure TPlanet.setPopulation(Value:integer);
begin
  planetPopulation := Value;
end;

//============= PlanetList

constructor TPlanetList.Create();
begin
  inherited;
  Reset();
end;
destructor TPlanetList.Destroy();
begin
  Reset();
  inherited;
end;

procedure TPlanetList.Reset();
begin
  Count := 0;
  SetLength( Items, Count);
end;
procedure TPlanetList.addPlanet(theIndex,theOrbitPath:integer;theSystemName:string;theStarType:enumClimate;theStarSize:integer);
var chanceCLIMATE : TIntegerArray;
begin
  Inc( Count );
  SetLength( Items, Count);

  Items[Count-1] := TPlanet.Create();

  with Items[Count-1] do
  begin
    Name          := theSystemName+' '+IntToRoman( theIndex );
    Health        := 100;
    MaxHealth     := 100;
    chanceCLIMATE := TIntegerArray.Create('chanceClimate');

    case theStarType of
      climateREDSTAR    : chanceClimate.setArrayValues('30 20 10 5 3');
      climateYELLOWSTAR : chanceClimate.setArrayValues('3 15 30 15 3');
      climateBLUESTAR   : chanceClimate.setArrayValues('3 5 10 20 30');
    end;

    if (Random( chanceClimate.addedValue ) < chanceCLIMATE.getItem(0) ) then planetClimate := climateICE    else
    if (Random( chanceClimate.addedValue ) < chanceCLIMATE.getItem(1) ) then planetClimate := climateOCEAN  else
    if (Random( chanceClimate.addedValue ) < chanceCLIMATE.getItem(2) ) then planetClimate := climateGAIA   else
    if (Random( chanceClimate.addedValue ) < chanceCLIMATE.getItem(3) ) then planetClimate := climateGAS    else
                                                                             planetClimate := climateDESERT;
    Size             := Random(10)+1;

    planetRotation         := (1+((SettingsINI.iMaxOrbits-theOrbitPath)))/Size; // Planets closer to the star orbit faster, but bigger objects orbit slower
    planetInitialRotation  := Random(360);
    planetOrbitDistance    := 500*((theOrbitPath+1)*2);

    case Size of
      1..3  : planetGravity := gravityLOW;
      4..7  : planetGravity := gravityNORMAL;
      8..10 : planetGravity := gravityHIGH;
    end;

    case planetClimate of
      climateICE    : begin planetGrowth := 1; planetMineral := mineralRICH;     DevConsole.Print(LOG_DEBUG2, 'addPlanet: Discovered an ICE planet: Growth #+1, Mineral #RICH, Size #'+IntToStr(Size)      ); end;
      climateOCEAN  : begin planetGrowth := 2; planetMineral := mineralABUNDENT; DevConsole.Print(LOG_DEBUG2, 'addPlanet: Discovered an OCEAN planet: Growth #+2, Mineral #ABUNDENT, Size #'+IntToStr(Size)); end;
      climateGAIA   : begin planetGrowth := 4; planetMineral := mineralPOOR;     DevConsole.Print(LOG_DEBUG2, 'addPlanet: Discovered a GAIA planet: Growth #+4, Mineral #POOR, Size #'+IntToStr(Size)      ); end;
      climateGAS    : begin planetGrowth := 2; planetMineral := mineralABUNDENT; DevConsole.Print(LOG_DEBUG2, 'addPlanet: Discovered a GAS planet: Growth #+2, Mineral #ABUNDENT, Size #'+IntToStr(Size)   ); end;
      climateDESERT : begin planetGrowth := 1; planetMineral := mineralRICH;     DevConsole.Print(LOG_DEBUG2, 'addPlanet: Discovered a DESERT planet: Growth #+1, Mineral #RICH, Size #'+IntToStr(Size)    ); end;
    end;

    Vector2D.setVector2D( 0, planetOrbitDistance );

  end;

  FreeAndNil( chanceClimate )
end;

end.

